﻿using ArtClub.DAL;
using ArtClub.Model;
using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Text.RegularExpressions;

namespace ArtClub.Controller
{
    public class MemberCtr : IMemberCtr
    {
        private IMemberDB memberDB;

        public MemberCtr()
        {
            memberDB = new MemberDB();
        }

        public Member GetMember(int id)
        {
            return memberDB.GetMember(id);
        }

        public void CreateMember(Member member)
        {
			ValidateMember(member);

            member.CreationDate = DateTime.Now;
            memberDB.CreateMember(member);
        }

		private void ValidateMember(Member member)
		{
			Regex matchEmail = new Regex(@"^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,4})$");
			Regex matchSSN = new Regex("^[0-9]{10}$");

			if (string.IsNullOrEmpty(member.Name))
				throw new Exception("Name is not correct");

			if (string.IsNullOrEmpty(member.Division))
				throw new Exception("Division is not correct");

			if (string.IsNullOrEmpty(member.Address))
				throw new Exception("Address is not correct");

			if (string.IsNullOrEmpty(member.City))
				throw new Exception("City is not correct");

			if (string.IsNullOrEmpty(member.Email) || !matchEmail.IsMatch(member.Email))
				throw new Exception("Email is not correct");

			if (string.IsNullOrEmpty(member.SSN) || !matchSSN.IsMatch(member.SSN))
			{
				throw new Exception("SSN is not correct");
			}
		}

        public List<Member> ListMembers()
        {
            return memberDB.ListMembers();
        }

        public List<Member> ListMembersByName(string name)
        {
            return memberDB.ListMembersByName(name);
        }

        public List<Member> ListMembersByEmail(string email)
        {
            return memberDB.ListMembersByEmail(email);
        }

        public List<Member> ListMembersByPoints(int minPoints)
        {
            return memberDB.ListMembersByPoints(minPoints);
        }

        public void AddPoints(Member member, int points)
        {
            if (points <= 0)
            {
                throw new PointException("Point value to be added is invalid");
            }

            if (member.Points + points > 3000)
            {
                throw new PointException("Point limit (3000 points) is reached");
            }

            memberDB.AddPoints(member, points);
        }

        public void RemovePoints(Member member, int points)
        {
            if (member.Points - points >= 0)
            {
                memberDB.RemovePoints(member, points);
            }
            else
            {
                throw new PointException("Points cannot go below 0");
            }
        }

		public void UpdateMember(Member member)
		{
			ValidateMember(member);
			memberDB.UpdateMember(member);
		}
		public void DeleteMember(int id)
		{
			memberDB.DeleteMember(id);
		}
	}

    public class PointException : Exception
    {
        public PointException(string message)
            : base(message)
        {
        }
    }

    public class CreateMemberException : Exception
    {
        public CreateMemberException(string message)
            : base(message)
        {
        }
    }
}